//语法：new Promise( function(resolve, reject) {...} /* executor */  )
/**
 * * 构建promise对象的时候,需要传入一个 executor 函数
 * * 主要的业务流程都在executor函数中执行
 * 
 * * Promise构造函数执行时立即调用executor 函数
 * * resolve 和 reject 两个函数作为参数传递给executor
 * 
 * * resolve函数被调用时,将promise的状态改为fulfilled
 * * reject函数被调用时,将promise状态改为rejected
 * * 一旦状态改变，就不会再变
 * 
 * * executor调用resolve函数时,会触发promise.then设置的回调函数
 * * executor调用reject函数时,会触发promise.catch设置的回调函数
 * 
 * * Promise中不能自定义使用try/catch进行错误捕获
 */



/**
 * * Promise 是用来管理异步编程的，它本身不是异步的
 * * new Promise的时候会立即把executor函数执行
 */

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('1111');
  }, 1000)
  console.log('2222');
})
console.log('3333');      //2222 3333 1111


/**
 * * Promise 采用了回调函数延迟绑定技术
 * * new Promise的时候先执行executor函数，打印出 1、2，
 * * Promise在执行resolve时，触发微任务，还是继续往下执行同步任务，
 * * 执行p1.then时，存储起来两个函数（此时这两个函数还没有执行）,
 * * 然后打印出3，此时同步任务执行完成，最后执行刚刚那个微任务，
 * * 从而执行.then中成功的方法。
 */

let p2 = new Promise((resolve, reject) => {
  console.log(1);
  resolve('chan')
  // reject('qi')
  console.log(2);
})
// then:设置成功或者失败后处理的方法
p2.then(res => {
  console.log('success', res);
}, reason => {
  console.log('fail', reason);
})
console.log(3);   //1 2 3 success chan


/**
 * 错误处理
 */
function executor(resolve, reject) {
  let rand = Math.random()
  console.log(1);
  console.log(rand);
  if (rand < 5) { resolve() }
  else { reject() }
}
let p3 = new Promise(executor)
let p4 = p3.then(res => { console.log('p4'); return new Promise(executor) })
let p5 = p4.then(res => { console.log('p5'); return new Promise(executor) })
p3.catch(err => { console.log(err, 'error'); })
console.log(2);


/**
 *Promise链式调用(为什么可以链式调用)
 * * 每次你对Promise调用then，它都会创建并返回一个新的Promise，我们可以将其链接起来；
 * * 方法中如果返回一个新的Promise实例（如Promise.reject(1)），返回这个实例的结果是成功还是失败，也决定了当前实例是成功还是失败。
 * * 剩下的情况基本上都是让实例变为成功的状态，上一个then中方法返回的结果会传递到下一个then的方法中。
 */

// 决定了下个then中的成功的方法会被执行
let p6 = new Promise((resolve, reject) => { resolve(100) })
// 执行了成功的方法,但是返回了新的promise实例,这个新的实例决定了当前实例是失败的
// 所以下一个then中失败的方法会被执行
let p7 = p6.then(
  res => { console.log('success-p6', res); return Promise.reject(1) },
  reason => { console.log('fail-p6', reason); return 200 }
)
//
let p8 = p7.then(
  res => { console.log('success-p7', res); },
  reason => { console.log('fail-p7', reason); }
)


new Promise(resolve => {
  resolve(a)
}).then( 
  res =>{console.log('success-'+res); return res*10},
  fail => {console.log('fail-' + fail);}
).then( 
  res =>{console.log('success1-'+res); return res*10},
  fail => {console.log('fail1-' + fail);}
)
// a is undefined success-undefined  



